#include "demo.h"
#include "codeports.h"

typedef struct
{
	BOX box;
} Fire;

void
DEMO_Init(DEMO *demo, BOX *box)
{
	Fire *fire;
	demo->box = box;
	demo->data = malloc(sizeof(Fire));
	fire = demo->data;
	BOX_Allocate(&fire->box, box->info.width, box->info.height);
	BOX_Clear(&fire->box);
}

void
DEMO_Frame(DEMO *demo)
{
	Fire *fire = demo->data;
	float x, y, c, r, g, b;
	for(x = 0; x < fire->box.info.width; x += 1.0f)
	{
		c = abs(32768 + rand()) % 256;
		r = abs(32768 + rand()) % 256;
		g = abs(32768 + rand()) % 256 / 4;
		b = abs(32768 + rand()) % 256 / 16;
		switch(fire->box.info.bpp)
		{
			case 1:
				BOX_SetPixelColor(&fire->box, x, fire->box.info.height - 1, c);
				BOX_SetPixelColor(demo->box, x, fire->box.info.height - 1, c);
				break;
			case 2:
			case 3:
			case 4:
				BOX_SetPixelRGB(&fire->box, x, fire->box.info.height - 1, r, g, b);
				BOX_SetPixelRGB(demo->box, x, fire->box.info.height - 1, r, g, b);
				break;
		}
	}
	for(x = 0; x < fire->box.info.width; x += 1.0f)
	{
		for(y = 0; y < fire->box.info.height; y += 1.0f)
		{
			switch(fire->box.info.bpp)
			{
				case 1:
					c = ((fire->box.buffer[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x - 1 + fire->box.info.width) % fire->box.info.width))] + fire->box.buffer[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + ((unsigned int) x % fire->box.info.width))] + fire->box.buffer[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x + 1) % fire->box.info.width))] + fire->box.buffer[(unsigned int) ((((unsigned int) y + 2) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x) % fire->box.info.width))]) * 32) / 129;
					BOX_SetPixelColor(&fire->box, x, y, c);
					BOX_SetPixelColor(demo->box, x, y, c);
					break;
				case 2:
					r = (((((((unsigned short *) fire->box.buffer)[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x - 1 + fire->box.info.width) % fire->box.info.width))] & 0xF800) >> 11) << 3) + (((((unsigned short *) fire->box.buffer)[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + ((unsigned int) x % fire->box.info.width))] & 0xF800) >> 11) << 3) + (((((unsigned short *) fire->box.buffer)[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x + 1) % fire->box.info.width))] & 0xF800) >> 11) << 3) + (((((unsigned short *) fire->box.buffer)[(unsigned int) ((((unsigned int) y + 2) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x) % fire->box.info.width))] & 0xF800) >> 11) << 3)) * 32) / 129;
					g = (((((((unsigned short *) fire->box.buffer)[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x - 1 + fire->box.info.width) % fire->box.info.width))] & 0x07E0) >> 5) << 2) + (((((unsigned short *) fire->box.buffer)[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + ((unsigned int) x % fire->box.info.width))] & 0x07E0) >> 5) << 2) + (((((unsigned short *) fire->box.buffer)[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x + 1) % fire->box.info.width))] & 0x07E0) >> 5) << 2) + (((((unsigned short *) fire->box.buffer)[(unsigned int) ((((unsigned int) y + 2) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x) % fire->box.info.width))] & 0x07E0) >> 5) << 2)) * 32) / 129;
					b = (((((((unsigned short *) fire->box.buffer)[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x - 1 + fire->box.info.width) % fire->box.info.width))] & 0x001F)) << 3) + (((((unsigned short *) fire->box.buffer)[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + ((unsigned int) x % fire->box.info.width))] & 0x001F)) << 3) + (((((unsigned short *) fire->box.buffer)[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x + 1) % fire->box.info.width))] & 0x001F)) << 3) + (((((unsigned short *) fire->box.buffer)[(unsigned int) ((((unsigned int) y + 2) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x) % fire->box.info.width))] & 0x001F)) << 3)) * 32) / 129;
					BOX_SetPixelRGB16(&fire->box, x, y, r, g, b);
					BOX_SetPixelRGB16(demo->box, x, y, r, g, b);
					break;
				case 3:
				case 4:
					r = ((fire->box.buffer[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x - 1 + fire->box.info.width) % fire->box.info.width)) * fire->box.info.bpp + 0] + fire->box.buffer[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + ((unsigned int) x % fire->box.info.width)) * fire->box.info.bpp + 0] + fire->box.buffer[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x + 1) % fire->box.info.width)) * fire->box.info.bpp + 0] + fire->box.buffer[(unsigned int) ((((unsigned int) y + 2) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x) % fire->box.info.width)) * fire->box.info.bpp + 0]) * 32) / 129;
					g = ((fire->box.buffer[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x - 1 + fire->box.info.width) % fire->box.info.width)) * fire->box.info.bpp + 1] + fire->box.buffer[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + ((unsigned int) x % fire->box.info.width)) * fire->box.info.bpp + 1] + fire->box.buffer[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x + 1) % fire->box.info.width)) * fire->box.info.bpp + 1] + fire->box.buffer[(unsigned int) ((((unsigned int) y + 2) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x) % fire->box.info.width)) * fire->box.info.bpp + 1]) * 32) / 129;
					b = ((fire->box.buffer[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x - 1 + fire->box.info.width) % fire->box.info.width)) * fire->box.info.bpp + 2] + fire->box.buffer[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + ((unsigned int) x % fire->box.info.width)) * fire->box.info.bpp + 2] + fire->box.buffer[(unsigned int) ((((unsigned int) y + 1) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x + 1) % fire->box.info.width)) * fire->box.info.bpp + 2] + fire->box.buffer[(unsigned int) ((((unsigned int) y + 2) % fire->box.info.height) * fire->box.info.width + (((unsigned int) x) % fire->box.info.width)) * fire->box.info.bpp + 2]) * 32) / 129;
					BOX_SetPixelRGB(&fire->box, x, y, r, g, b);
					BOX_SetPixelRGB(demo->box, x, y, r, g, b);
					break;
					break;
			}
		}
	}
}

void
DEMO_Final(DEMO *demo)
{
	Fire *fire = demo->data;
	BOX_Free(&fire->box);
	free(demo->data);
}
